<?php


namespace App\Controller;


use Common\Model\MemberModel;
use SidToken\Model\SidTransferLogModel;
use SidToken\Model\SidTrxErrModel;
use SidToken\Utils\MemberWalletUtil;
use SidToken\Utils\TrxRpc;
use User\Model\UcenterMemberModel;

class WalletController extends AppBaseController
{
    public function importMnemonic()
    {
        $mnemonic = I("mnemonic", "", "op_t");
        //$mnemonic = preg_replace('# #', '', $mnemonic);
        $password = I("password");
        $walletName = I("wallet_name", '', 'op_t');
        if ($walletName == null) {
            $this->jerror('钱包名称不能为空');
        }
        if (strlen($walletName) < 4 || strlen($walletName) > 12) {
            $this->jerror("钱包名称4-12位");
        }
        if (strlen($password) < 8) {
            $this->jerror("密码长度至少8位");
        }
        if (strlen($password) > 16) {
            $this->jerror("密码长度不能高于16位");
        }
        $mnemonicArr = explode(" ", $mnemonic);
        if (sizeof($mnemonicArr) != 12) {
            $this->jerror("助记词错误，助记词应由12个单词组成");
        }
        $uid = M("Member")->where(['wallet_eth_mnemonic' => strtolower($mnemonic)])->getField("uid");
        if (!$uid) {//TODO 注册流程,目前直接拒绝
            $this->jerror("该助记词非我们会员");
        }

        $UcenterMember = new UcenterMemberModel();
        $UcenterMember->changeWalletNameAndPassword($uid, $walletName, $password); //通过账号密码取到uid

        $Member = new MemberModel();
        $Member->login($uid, true, 0); //登陆


        $user = query_user(array('wallet_name', 'wallet_address', 'wallet_eth_private_key', 'avatar64'), $uid);

        $token = array(
            'uid' => $uid,
            'expire_time' => time() + 86400 * 10000//永久生效
        );
        $token = base64_encode(json_encode($token));

        $return = array(
            "avatar" => $user['avatar64'],
            "uid" => $uid,
            'token' => $token,
            'wallet_name' => $walletName,
            'wallet_private_key' => $user['wallet_eth_private_key'],
            'wallet_address' => $user['wallet_address']
        );
        $this->jsuccess($return);
    }

    public function importPrivateKey()
    {
        $privateKey = I("private_key");
        $password = I("password");
        $walletName = I("wallet_name", '', 'op_t');

        if ($walletName == null) {
            $this->jerror('钱包名称不能为空');
        }
        if (strlen($walletName) < 4 || strlen($walletName) > 12) {
            $this->jerror("钱包名称4-12位");
        }
        if (strlen($password) < 8) {
            $this->jerror("密码长度至少8位");
        }
        if (strlen($password) > 16) {
            $this->jerror("密码长度不能高于16位");
        }
        //$imei = I('imei', '', 'op_t');

        //TODO privateKey查询，若在系统中存在走登录流程，否则走注册流程，目前只实现登录流程
        $uid = M("Member")->where(['wallet_eth_private_key' => $privateKey])->getField("uid");
        if (!$uid) {//TODO 注册流程,目前直接拒绝
            $this->jerror("该私钥钱包非我们会员");
        }

        $UcenterMember = new UcenterMemberModel();
        $UcenterMember->changeWalletNameAndPassword($uid, $walletName, $password); //通过账号密码取到uid

        $Member = new MemberModel();
        $Member->login($uid, true, 0); //登陆


        $user = query_user(array('wallet_name', 'wallet_address', 'wallet_eth_private_key', 'avatar64'), $uid);

        $token = array(
            'uid' => $uid,
            'expire_time' => time() + 86400 * 10000//永久生效
        );
        $token = base64_encode(json_encode($token));

        $return = array(
            "avatar" => $user['avatar64'],
            "uid" => $uid,
            'token' => $token,
            'wallet_name' => $walletName,
            'wallet_private_key' => $user['wallet_eth_private_key'],
            'wallet_address' => $user['wallet_address']
        );
        $this->jsuccess($return);

    }

    public function generalUserEthWallet()
    {
        $Member = new MemberModel();
        $users = $Member->select();
        foreach ($users as &$user) {
            $result = curlGet("http://eth-tools-demo.btcsoft.cn/index.php");
            $result = json_decode($result, true);
            if ($result['status'] == 1) {
                $data = $result['data'];
                $user['wallet_eth_mnemonic'] = $data['mnemonic'];
                $user['wallet_eth_seed'] = $data['seed'];
                $user['wallet_eth_public_key'] = $data['public_key'];
                $user['wallet_eth_private_key'] = $data['private_key'];
                $user['wallet_eth_address'] = $data['address'];
                $Member->save($user);
            }
        }
        $this->jsuccess($users);

    }

    public function createWallet()
    {
        $walletName = I("wallet_name", '', 'op_t');
        $password = I("password");
        $inviteCode = I("invite_code");

        $aRegType = 'username';
        $username = "account" . time() . mt_rand(1000, 9999);
        $role = 1;
        if ($walletName == null) {
            $this->jerror('钱包名称不能为空');
        }
        if (strlen($walletName) < 4 || strlen($walletName) > 12) {
            $this->jerror("钱包名称4-12位");
        }
        if ($inviteCode == null) {
            $this->jerror("请填写邀请码");
        }
        //注册用户
        $return = check_action_limit('reg', 'ucenter_member', 1, 1, true);
        if ($return && !$return['state']) {
            $this->jerror($return['info']);
        }

        if (strlen($password) < 8) {
            $this->jerror("密码长度至少8位");
        }
        if (strlen($password) > 16) {
            $this->jerror("密码长度不能高于16位");
        }

        //if ($inviteCode) {
        if (!$this->checkInviteCode($inviteCode)) {
            $this->jerror("邀请码不存在！");
        }
        //}

        /* 注册用户 */
        $UcenterMember = new UcenterMemberModel();

        $nickname = $username;
        //获取注册类型
        check_username($username, $email, $mobile, $aUnType);

        $uid = $UcenterMember->register($username, $nickname, $password, $email, $mobile, $aUnType);
        //注册方式统计

        if (0 < $uid) { //注册成功
            register_mark($uid, 'app', $aRegType);

            //保存钱包信息
            $TrxRpcUtil = new TrxRpc();
            $eth = $TrxRpcUtil->getEthAddress();
            $eth = $eth['data'];
            $result = $TrxRpcUtil->getAddress($username);
            $walletInfo = [];
            if ($result['status'] == 1) {
                $walletInfo = [
                    'wallet_name' => $walletName,
                    'wallet_address' => $result['data']['address'],
                    'wallet_private_key' => '',
                ];
                //保存eth信息
                $walletInfo['wallet_eth_mnemonic'] = $eth['mnemonic'];
                $walletInfo['wallet_eth_seed'] = $eth['seed'];
                $walletInfo['wallet_eth_public_key'] = $eth['public_key'];
                $walletInfo['wallet_eth_private_key'] = $eth['private_key'];
                $walletInfo['wallet_eth_address'] = $eth['address'];

                $ret = M("Member")->where(['uid' => $uid])->save($walletInfo);

            } else {
                $this->jerror("创建钱包失败");
            }


            //奖励推荐用户、并关注推荐人\生成邀请人
            if ($inviteCode) {
                $this->initInviteUser($uid, $inviteCode, 1);
            }
            //初始化角色
            $UcenterMember->initRoleUser($role, $uid);
            $uid = $UcenterMember->login($username, $password, $aUnType); //通过账号密码取到uid

            $this->createCode($uid);

            $token = array(
                'uid' => $uid,
                'expire_time' => time() + 86400 * 10000//永久生效
            );
            $token = base64_encode(json_encode($token));

            $return = array(
                "avatar" => '',
                "uid" => $uid,
                'token' => $token,
                'wallet_name' => $walletName,
                'wallet_private_key' => $walletInfo['wallet_eth_private_key'],
                'wallet_address' => $walletInfo['wallet_address']
            );
            $this->jsuccess($return);
        } else { //注册失败，显示错误信息
            set_user_status($uid, 4);
            $this->jerror($this->showRegError($uid));
        }
    }

    public function preVerifyMnemonic()
    {
        $uid = $this->getUid();
        $walletEth = query_user(['wallet_name', 'wallet_address', 'wallet_private_key', 'wallet_eth_mnemonic', 'wallet_eth_seed', 'wallet_eth_public_key', 'wallet_eth_private_key', 'wallet_eth_address'], $uid);
        $mnemonic = $walletEth['wallet_eth_mnemonic'];
        $mnemonicArr = explode(" ", $mnemonic);
        $check1 = mt_rand(0, 5);
        $check2 = mt_rand(6, 11);
        $return = [
            'check1' => $check1,
            'check2' => $check2,
            'mnemonic' => $mnemonic,
            'mnemonic_arr' => $mnemonicArr
        ];
        $this->jsuccess($return);
    }

    public function verifyMnemonic()
    {
        $uid = $this->getUid();
        $walletEth = query_user(['wallet_name', 'wallet_address', 'wallet_private_key', 'wallet_eth_mnemonic', 'wallet_eth_seed', 'wallet_eth_public_key', 'wallet_eth_private_key', 'wallet_eth_address'], $uid);
        $mnemonic = $walletEth['wallet_eth_mnemonic'];
        $mnemonicArr = explode(" ", $mnemonic);

        $check1 = I("check1", 0, 'intval');
        $check2 = I("check2", 0, 'intval');
        $answer1 = I("answer1", '', 'op_t');
        $answer2 = I("answer2", '', 'op_t');
        if ($mnemonicArr[$check1] == $answer1 && $mnemonicArr[$check2] == $answer2) {
            $Member = new MemberModel();
            $Member->where(['uid' => $uid])->setField("is_backup_wallet", 1);
            $this->jsuccess($walletEth);
        } else {
            $this->jerror("助记词校验错误");
        }
    }

    public function getAccount()
    {
        $uid = $this->getUid();
        $Wallet = new MemberWalletUtil();
        $this->jsuccess($Wallet->getWallet($uid));
    }

    /**
     * 获取用户充值地址
     */
    public function walletAddress()
    {
        //$this->jsuccess();
        $uid = $this->getUid();
        $user = query_user('wallet_address', $uid);
        $Member = new MemberModel();
        $TrxRpc = new TrxRpc();
        if ($user['wallet_address'] == null) {
            $username = "account" . $uid . mt_rand(1000, 9999);
            $result = $TrxRpc->getAddress($username);
            if ($result['status'] == 1) {
                $Member->where(['uid' => $uid])->save([
                    'nickname' => $username,
                    'wallet_address' => $result['data']['address']
                ]);
                clean_query_user_cache($uid, ['nickname', 'wallet_address']);
                $this->jsuccess($result['data']['address']);
            } else {
                $this->jerror("无法获取充币地址");
            }
        } else {
            $this->jsuccess($user['wallet_address']);
        }
    }

    public function balance()
    {
        $symbol = I("symbol", 'USDT', 'op_t');
        $uid = $this->getUid();

        if (strtoupper($symbol) == "USDT") {
            $balance = get_user_usdt_balance($uid);
        } else {
            $balance = get_user_sid_balance($uid);
        }
        $this->jsuccess(floatval($balance));
    }

    public function getPrivateKey()
    {
        $uid = $this->getUid();
        $this->checkPassword($uid);
        $privateKey = query_user('wallet_eth_private_key', $uid);
        $this->jsuccess($privateKey['wallet_eth_private_key']);
    }

    private function withdrawCheck($symbol, $amount, $uid, $address)
    {
        if (strtolower($symbol) != 'sid') {
            return;
        }
        $toAddressUid = getUidByAddress($address);
        if ($toAddressUid != -1) {//平台内转账不受限制
            return;
        }
        /*
         * SID提币到外部交易所或者钱包 限制每周五提币一次，一次不能大于400个
            APP内转不限制
             提币的时候不到时间或者金额大于400     系统自动拒绝   提示：
            没到开放时间或提币金额大于400
         */
//        $weekarray = array(0, 1, 2, 3, 4, 5, 6); //先定义一个数组
//        $day = $weekarray[date("w")];
//        if ($day != 5) {
//            $this->jerror("每周五才能提币");
//        }
//        if ($amount > 400) {
//            $this->jerror("数量不能大于400");
//        }
        $TransferLogModel = new SidTransferLogModel();
        $map['symbol'] = strtoupper("SID");
        $map['reason'] = '钱包转出，扣除手续费5SID';
        $map['type'] = 'SID转出';
        $map['status'] = array('neq', $TransferLogModel::STATUS_FAIL);
        $map['create_time'] = array('egt', strtotime(date("Ymd")));
        $map['uid'] = $uid;

        $res = $TransferLogModel->field("IFNULL(SUM(amount),0) totalamount")->where($map)->find();
        $totalAmount = $res['totalamount'];
//        if ($totalAmount + $amount > 400) {
//            $this->jerror("单日数量不能超过400");
//        }


    }

    public function withdraw()
    {
        $uid = $this->getUid();
        $this->checkPassword($uid);
        $amount = I("amount", 0, 'floatval');
        $symbol = I("symbol", '', 'op_t');

        if ($amount <= 0) {
            $this->jerror("数量需要大于0");
        }
        $address = I("address", '', 'op_t');
        if (!$address) {
            $this->jerror("请输入收款地址");
        }
        $userAddress = get_address($uid);
        if ($address == $userAddress) {
            $this->jerror("不能给自己的地址转币");
        }
        $this->withdrawCheck($symbol, $amount, $uid, $address);

        $Member = new MemberModel();
        $MemberWallet = new MemberWalletUtil();
        $balance = $Member->where(['uid' => $uid])->field("score1,score2,status")->find();
        if (!$balance) {
            $this->jerror("用户不存在");
        }
        if ($balance['status'] != 1) {
            $this->jerror("您的账户被锁定，请联系客服");
        }
        if (strtoupper($symbol) == 'SID') {
            if ($amount - $balance['score1'] > 0) {
                $this->jerror("余额不足，最多提币{$balance['score1']}SID");
            }
        } else {
            //暂未开放
            $this->jerror("暂未开放");
            exit;
//            if ($amount - $balance['score2'] > 0) {
//                $this->jerror("余额不足，最多提币{$balance['score2']}USDT");
//            }
        }

        $withdrawConfig = C("SID_ADDRESS_LIST.withdraw");

        $withdrawAddress = $withdrawConfig['address'];
        $txid = time() . mt_rand(10000, 99999);
        $TransferLog = new SidTransferLogModel();
        //保存订单信息
        if (strtoupper($symbol) == 'SID') {//提现sid需扣除5sid 手续费
            if ($amount <= 5) {
                $this->jerror("SID提币数量需大于5");
            }
            $orderSn = $MemberWallet->changeSid($uid, 'dec', $withdrawAddress, $address, $txid, $amount, "钱包转出，扣除手续费5SID", $TransferLog::STATUS_UNCHECK);
        } else {
            $orderSn = $MemberWallet->changeUsdt($uid, 'dec', $withdrawAddress, $address, $txid, $amount, "钱包转出", $TransferLog::STATUS_UNCHECK);
        }
        $return = [
            'from' => $withdrawAddress,
            'to' => $address,
            'type' => strtoupper($symbol) . '转出',
            'txid' => $txid,
            'create_time' => date("Y-m-d H:i:s"),
        ];
        $this->jsuccess($return);


    }

    /**
     * 转账记录
     */
    public function transferLog()
    {
        $page = I("page", 1, 'intval');
        $symbol = I("symbol", "", "op_t");
        $uid = $this->getUid();
        $TransferLog = new SidTransferLogModel();
        $map = [
            'uid' => $uid
        ];
        if ($symbol != "") {
            $map['symbol'] = strtoupper($symbol);
        }
        $lists = $TransferLog->where($map)->order("create_time DESC")->page($page, 20)->select();
        foreach ($lists as &$val) {
            $val['create_time'] = date("Y-m-d H:i:s", $val['create_time']);
            $prefix = "";
            if (strpos($val['type'], '转出') !== false) {
                $prefix = "-";
            }
            if (strpos($val['type'], '转入') !== false) {
                $prefix = "+";
            }
            $val['amount'] = $prefix . floatval($val['amount']);
            $reasonPrefix = $this->getStatusStr($val['status']);
            $val['status_str'] = $reasonPrefix;
        }
        $this->jsuccess($lists);
    }

    private function getStatusStr($status)
    {
        if ($status == 0) {
            return "待审核";
        } else if ($status == 1) {
            return "成功";
        } else {
            return "拒绝";
        }
    }
}